use std::sync::{Arc, Mutex};
use serde_json::{json, Value};
use tokio::sync::mpsc;

pub struct AppState {
    pub tx: Arc<Broadcaster>,
}

struct BroadcasterInner {
    clients: Vec<mpsc::Sender<String>>,
    json_clients: Vec<mpsc::Sender<Value>>
}
pub struct Broadcaster {
    inner: Mutex<BroadcasterInner>,
}

impl Broadcaster {
    pub fn new() -> Arc<Self> {
        Arc::new(Broadcaster {
            inner: Mutex::new(BroadcasterInner {
                clients: Vec::new(),
                json_clients: Vec::new()
            })
        })
    }
    pub async fn add_str_client(&self) -> mpsc::Receiver<String> {
        let (tx, rx) = mpsc::channel::<String>(10);
        tx.send("welcome".to_string()).await.unwrap();
        self.inner.lock().unwrap().clients.push(tx);
        rx
    }
    pub async fn send_str(&self, msg: &str) {
        let clients = self.inner.lock().unwrap().clients.clone();
        let send_futures = clients.iter().map(|client| client.send(msg.to_string()));
        let _ = futures_util::future::join_all(send_futures).await;
    }
    // json
    pub async fn add_client(&self) -> mpsc::Receiver<Value> {
        let (tx, rx) = mpsc::channel::<Value>(100);
        tx.send(json!({ "code": 100, "msg": "连接成功" })).await.unwrap();
        self.inner.lock().unwrap().json_clients.push(tx);
        rx
    }
    pub async fn send(&self, msg:Value) {
        let clients = self.inner.lock().unwrap().json_clients.clone();
        let send_futures = clients.iter().map(|client| client.send(msg.to_owned()));
        let _ = futures_util::future::join_all(send_futures).await;
    }
}

pub fn state() -> Arc<AppState> {
    // let (tx, _rx) = broadcast::channel(16);
    let tx = Broadcaster::new();
    Arc::new(AppState { tx })
}